import { IBreadCrumb } from '@/base-ui/breadCrumb';
import { RouteRecordRaw } from 'vue-router';
let firstMenu: any; // 为了用户打开main页面的时候自动跳到第一个注册的menu上面

// 从服务器请求来的userMenu 接收一个any[], 返回一个符合router.routes的数组
export function mapMenusToRoutes(userMenus: any[]): RouteRecordRaw[] {
  const routes: RouteRecordRaw[] = [];

  // 1.先去加载默认的所有路由
  const allRoutes: RouteRecordRaw[] = []; // 储存所有路由的数组
  // require是webpack自带的对象
  // routeFiles[]储存的所有ts文件的路径 -> ./system/department/department.ts. 得到路径是相对与context传入的第一个参数.
  const routeFiles = require.context('../router/main', true, /\.ts/); // 读取所有的ts文件
  routeFiles.keys().forEach((key) => {
    // 这个require是CommonJs的require
    const route = require('../router/main' + key.slice(1));
    allRoutes.push(route.default);
  });

  // 2.根据userMenu获取需要添加的routes (内部函数)
  const _recurseGetRoutes = (menus: any[]) => {
    for (const menu of menus) {
      // 是否还有子目录
      if (menu.type == 1) {
        _recurseGetRoutes(menu.children);
      }
      // 开始匹配路由
      allRoutes.map((route) => {
        if (route.path === menu.url) {
          routes.push(route);
          // 如果firstMenu没有值就给它赋值, 再去导航守卫里面使用
          if (!firstMenu) {
            firstMenu = menu;
          }
        }
      });
    }
  };
  // 拿到所有需要被注册的路由
  _recurseGetRoutes(userMenus);
  return routes;
}

// 这个函数的作用是 通过路径拿到面包屑的层级. 制作面包屑.
export function pathMapBreadCrumbs(userMenu: any[], currentPath: string) {
  const breadCrumbs: IBreadCrumb[] = [];
  pathMapUserMenu(userMenu, currentPath, breadCrumbs);
  return breadCrumbs;
}

// 这个函数的作用是通过路径找到对应的main/menu, 让在切换menu后再点击刷新会自动打开这个menu的内容,拿到当前menu.id给el-menu的default-active再次刷新也会自动打开这个二级目录增加用户使用体验.
export function pathMapUserMenu(
  userMenu: any[],
  currentPath: string,
  breadCrumbs?: IBreadCrumb[]
): any {
  for (const menu of userMenu) {
    // 还有子菜单
    if (menu.type === 1) {
      // return pathMapUserMenu(menu.children ?? [], currentPath); // return就立刻结束了所有函数体,只有执行一次这就话.
      // 每次执行这个函数会返回 menu 与 undefinded. 判断它是否有值,有值就代表我们找到了.
      // 不然找到了也拿不到.
      const target = pathMapUserMenu(menu.children ?? [], currentPath);
      if (target) {
        // 用参数赋值
        breadCrumbs?.push({ name: menu.name, path: menu.name }); // 一级目录
        breadCrumbs?.push({ name: target.name, path: target.url }); // 二级目录
        return target;
      }
    }
    // 匹配成功
    if (menu.url === currentPath) {
      return menu;
    }
  }
}

// 得到所有的按钮的permission
export function mapMenusToPermissions(userMenus: any[]) {
  const permissions: string[] = [];

  const _recurseGetPermission = (menus: any[]) => {
    for (const menu of menus) {
      if (menu.type === 1 || menu.type === 2) {
        _recurseGetPermission(menu.children ?? []);
      } else if (menu.type === 3) {
        permissions.push(menu.permission);
      }
    }
  };
  _recurseGetPermission(userMenus);
  return permissions; // 一直都是往一个数组里面push
}

export function mapMenuToLeafKeys(menuList: any[]) {
  const leftKeys: number[] = [];

  const _recurseGetLeaf = (menuList: any[]) => {
    for (const menu of menuList) {
      if (menu.children) {
        _recurseGetLeaf(menu.children);
      } else {
        leftKeys.push(menu.id);
      }
    }
  };

  _recurseGetLeaf(menuList);
  return leftKeys;
}

export { firstMenu };

/* 动态注册路由的步骤
1.将发送请求拿到的 userMenu 传到mapMenuSToRoutes函数当中.
2.mapMenuSToRoutes函数先动态加载所有路由(应用的所有的路由),再对比传进来的userMenu数组.
3.根据userMenu有的路由动态注册路由. router.addRoute();
 */
